﻿using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Net;
using System.Net.Security;
using System.Security.Cryptography.X509Certificates;
using System.Text;
using System.Text.RegularExpressions;
using System.Web;
using System.Windows.Forms;
using Codeplex.Data;

namespace AL.Helper
{

    public class ArticleAnalyzingResult
    {
        public int PraiseCount { get; set; }
        public int ReadingCount { get; set; }
        public string ArticleReadingCountURL { get; set; }
        public string Header { get; set; }
        public string Context { get; set; }
        public bool IsDeleted { get; set; }
        public DateTime RefreshDate { get; set; }
        public string ArticleWithReadingCountURL { get; set; }
        public bool IsTimeout { get; set; }
    }


    public class ArticleCountsAnalyzer
    {
        private class ContextAnalyzer
        {
            private const string P = "var\\s+{0}\\s*=\\s*['\"]([^'\"]*)['\"]";
            private static readonly Regex readNum;
            private static readonly Regex likeNum;

            static ContextAnalyzer()
            {
                readNum = GetVariablePattern("read_num");
                likeNum = GetVariablePattern("like_num");
            }

            private static Regex GetVariablePattern(string variableName)
            {
                //return new Regex(string.Format("var\\s+{0}\\s*=\\s*['\"]([^'\"]*)['\"]", variableName), RegexOptions.IgnoreCase | RegexOptions.Compiled);

                const string pattern = @"\s*""?{0}""?:""?(\d*)""?\*1";
                return new Regex(string.Format(pattern, variableName), RegexOptions.IgnoreCase | RegexOptions.Compiled);
            }

            public int GetReadingCount(string context)
            {
                var match = readNum.Match(context);
                int result;
                if (match.Success)
                {
                    string value = match.Groups[1].Value;
                    result = this.ConvertToInt(value);
                }
                else
                {
                    result = -1;
                }
                return result;
            }

            public int GetPraiseCount(string context)
            {
                var match = likeNum.Match(context);
                int result;
                if (match.Success)
                {
                    string value = match.Groups[1].Value;
                    if (value == "赞")
                    {
                        result = 0;
                    }
                    else
                    {
                        result = this.ConvertToInt(value);
                    }
                }
                else
                {
                    result = -1;
                }
                return result;
            }

            private int ConvertToInt(string value)
            {
                value = value.Trim().Replace("+", "");
                int result;
                if (string.IsNullOrWhiteSpace(value))
                {
                    result = 0;
                }
                else
                {
                    int num = 0;
                    if (int.TryParse(value, out num))
                    {
                        result = num;
                    }
                    else
                    {
                        result = -2;
                    }
                }
                return result;
            }
        }

        private const string ARTICAL_URL = "https://wx.qq.com/cgi-bin/mmwebwx-bin/webwxcheckurl?requrl={0}";
        private const string UserAgent = "User-Agent: Mozilla/5.0 (iPad; CPU OS 6_0 like Mac OS X) AppleWebKit/536.26 (KHTML, like Gecko) Version/6.0 Mobile/10A5355d Safari/8536.25";
        private string weixinLoginCookie;
        private ContextAnalyzer contextAnalyzer = new ContextAnalyzer();

        public ArticleCountsAnalyzer(string weixinLoginCookie)
        {
            this.weixinLoginCookie = weixinLoginCookie;
        }

        //public ArticleAnalyzingResult AnalyzeArticle(string articleUrl)
        //{
        //    var webClient = new WebClient();
        //    webClient.Encoding = Encoding.UTF8;
        //    webClient.Headers.Add("Accept: text/html, application/xhtml+xml, */*");
        //    webClient.Headers.Add("User-Agent: Mozilla/5.0 (iPad; CPU OS 6_0 like Mac OS X) AppleWebKit/536.26 (KHTML, like Gecko) Version/6.0 Mobile/10A5355d Safari/8536.25");
        //    webClient.Headers.Add("Cache-Control: no-cache");
        //    webClient.Headers.Add(this.GetCookie());
        //    string headerString = this.GetHeaderString(webClient.Headers);
        //    ServicePointManager.ServerCertificateValidationCallback = ((object param0, X509Certificate param1, X509Chain param2, SslPolicyErrors param3) => true);
        //    string arg = HttpUtility.UrlEncode(articleUrl);
        //    string text = string.Format("https://wx.qq.com/cgi-bin/mmwebwx-bin/webwxcheckurl?requrl={0}", arg);
        //    string text2 = webClient.DownloadString(text);


        //    ArticleAnalyzingResult articleAnalyzingResult = new ArticleAnalyzingResult
        //                                                    {
        //                                                        Context = text2,
        //                                                        ArticleReadingCountURL = text,
        //                                                        Header = headerString,
        //                                                        ReadingCount = this.contextAnalyzer.GetReadingCount(text2),
        //                                                        PraiseCount = this.contextAnalyzer.GetPraiseCount(text2),
        //                                                        RefreshDate = DateTime.Now
        //                                                    };
        //    if (articleAnalyzingResult.ReadingCount == -1)
        //    {
        //        if (text2.IndexOf("该内容已被发布者删除") > 0)
        //        {
        //            articleAnalyzingResult.IsDeleted = true;
        //        }
        //    }
        //    return articleAnalyzingResult;
        //}

        public ArticleAnalyzingResult AnalyzeArticle(string articleUrl)
        {
            //// WebClient 模式
            //var webClient = new WebClient();
            //webClient.Encoding = Encoding.UTF8;
            //webClient.Headers.Add("Accept: text/html, application/xhtml+xml, */*");
            //webClient.Headers.Add("User-Agent: Mozilla/5.0 (iPad; CPU OS 6_0 like Mac OS X) AppleWebKit/536.26 (KHTML, like Gecko) Version/6.0 Mobile/10A5355d Safari/8536.25");
            //webClient.Headers.Add("Cache-Control: no-cache");
            //webClient.Headers.Add(this.GetCookie());
            //string headerString = this.GetHeaderString(webClient.Headers);
            ////ServicePointManager.ServerCertificateValidationCallback = ((object param0, X509Certificate param1, X509Chain param2, SslPolicyErrors param3) => true);
            //string arg = HttpUtility.UrlEncode(articleUrl);
            //string url = string.Format("https://wx.qq.com/cgi-bin/mmwebwx-bin/webwxcheckurl?requrl={0}", arg);
            //string content = webClient.DownloadString(url);


            // HttpWebRequest 模式
            var arg = HttpUtility.UrlEncode(articleUrl);
            var url = string.Format("https://wx.qq.com/cgi-bin/mmwebwx-bin/webwxcheckurl?requrl={0}", arg);

            var content = GetWebRequestString(url);
            if (string.IsNullOrWhiteSpace(content)) return null;

            var jsonObject = DynamicJson.Parse(content);
            if (string.IsNullOrWhiteSpace(jsonObject.FullURL)) return null;

            string articleCountUrl = jsonObject.FullURL;
            articleCountUrl = articleCountUrl.Replace("/s?", "/mp/getappmsgext?");
            content = GetWebRequestString(articleCountUrl);
            if (string.IsNullOrWhiteSpace(content)) return null;

            jsonObject = DynamicJson.Parse(content);
            //var readingCount = this.contextAnalyzer.GetReadingCount(content);
            //var praiseCount = this.contextAnalyzer.GetPraiseCount(content);
            int readingCount = ConvertToInt(jsonObject["appmsgstat"]["read_num"]);
            int praiseCount = ConvertToInt(jsonObject["appmsgstat"]["like_num"]);

            var articleAnalyzingResult = new ArticleAnalyzingResult
                                                            {
                                                                Context = content,
                                                                ArticleReadingCountURL = url,
                                                                //Header = headerString,
                                                                ReadingCount = readingCount,
                                                                PraiseCount = praiseCount,
                                                                RefreshDate = DateTime.Now
                                                            };
            if (articleAnalyzingResult.ReadingCount == -1)
            {
                if (content.IndexOf("该内容已被发布者删除") > 0)
                {
                    articleAnalyzingResult.IsDeleted = true;
                }
            }

            return articleAnalyzingResult;
        }

        private string GetWebRequestString(string url)
        {
            var content = string.Empty;
            try
            {
                // HttpWebRequest 模式
                var httpWebRequest = (HttpWebRequest) WebRequest.Create(url);
                httpWebRequest.Method = "GET";
                httpWebRequest.Accept = "text/html, application/xhtml+xml, */*";
                httpWebRequest.UserAgent =
                    "Mozilla/5.0 (iPad; CPU OS 6_0 like Mac OS X) AppleWebKit/536.26 (KHTML, like Gecko) Version/6.0 Mobile/10A5355d Safari/8536.25";
                httpWebRequest.Headers.Add("Cache-Control: no-cache");
                httpWebRequest.Headers.Add(this.GetCookie());
                httpWebRequest.AllowAutoRedirect = false;
                httpWebRequest.Timeout = 5000;
                httpWebRequest.ContentType = "application/x-www-form-urlencoded";


                var httpResponse = httpWebRequest.GetResponse();

                var stream = httpResponse.GetResponseStream();
                if (stream != null)
                {
                    var streamReader = new StreamReader(stream, Encoding.UTF8);
                    content = streamReader.ReadToEnd();
                }

            }
            catch (Exception ex)
            {
                // TODO:
                //MessageBox.Show(ex.Message);
                return content;
            }

            return content;
        }

        private int ConvertToInt(object value)
        {
            int result;
            if (value == null)
            {
                result = -1;
            }
            else
            {
                string text = value.ToString();
                text = text.Trim().Replace("+", "");
                if (string.IsNullOrWhiteSpace(text))
                {
                    result = 0;
                }
                else
                {
                    int num = 0;
                    if (int.TryParse(text, out num))
                    {
                        result = num;
                    }
                    else
                    {
                        result = -2;
                    }
                }
            }
            return result;
        }


        private string GetHeaderString(WebHeaderCollection headers)
        {
            var stringBuilder = new StringBuilder();
            for (int i = 0; i < headers.Count; i++)
            {
                stringBuilder.AppendLine(headers[i]);
            }
            return stringBuilder.ToString();
        }

        private string GetCookie()
        {
            return string.Format("Cookie: {0}", this.weixinLoginCookie);
        }
    }
}
